﻿using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using UpperComputer.Core.Entities;
using YFurion.Application;
using YFurion.Application.EFCore.Extensions;
using YFurion.Extensions;

namespace UpperComputer.Application
{
    public class BaseMenuButtonService : EFCoreApplicationService<BaseMenuButton, BaseMenuButtonResultDto, long, BaseMenuButtonResultRequestDto, BaseMenuButtonDto>, IBaseMenuButtonService
    {
        public async Task<PagedResultDto<BaseMenuButtonResultDto>> GetCustomAll(BaseMenuButtonResultRequestDto input, CancellationToken cancellationToken = default)
        {
            IQueryable<BaseMenuButtonResultDto> query = SlaveRepository.AsQueryable()
                .Join(MSRepository.Slave1<BaseMenu>().Where(bm => bm.IsActive), bmb => bmb.MenuCode, bm => bm.Code, (bmb, bm) => new BaseMenuButtonResultDto
                {
                    Id = bmb.Id,
                    Code = bmb.Code,
                    DisplayName = bmb.DisplayName,
                    MenuCode = bmb.MenuCode,
                    MenuName = bm.DisplayName,
                    Icon = bmb.Icon,
                    IsActive = bmb.IsActive,
                    IsSplit = bmb.IsSplit,
                    Sort = bmb.Sort,
                    CreationTime = bmb.CreationTime,
                    CreatorUserId = bmb.CreatorUserId,
                    LastModificationTime = bmb.LastModificationTime,
                    LastModifierUserId = bmb.LastModifierUserId,
                    Description = bmb.Description
                })
                .WhereIf(!input.MenuCode.IsNullOrWhiteSpace(), bmb => bmb.MenuCode.Equals(input.MenuCode))
                .WhereIf(!input.MenuName.IsNullOrWhiteSpace(), bmb => bmb.MenuName.StartsWith(input.MenuName));
            PagedResultDto<BaseMenuButtonResultDto> pagedResultDto = await query.ToPagedResultAsync(input, cancellationToken);
            return pagedResultDto;
        }

        public override async Task<BaseMenuButtonResultDto> Get(long id, CancellationToken cancellationToken = default)
        {
            BaseMenuButtonResultDto baseMenuButtonResultDto = await base.Get(id, cancellationToken);
            BaseMenu baseMenu = await MSRepository.Slave1<BaseMenu>().FirstOrDefaultAsync(m => m.Code.Equals(baseMenuButtonResultDto.MenuCode), cancellationToken: cancellationToken);
            baseMenuButtonResultDto.MenuName = baseMenu.DisplayName;
            return baseMenuButtonResultDto;
        }

        #region 新增和复制
        public override async Task<BaseMenuButtonResultDto> Post(BaseMenuButtonDto input, CancellationToken cancellationToken = default)
        {
            BaseMenuButton entity = await MasterRepository.AsQueryable(bmb => bmb.Code.Equals(input.Code) && bmb.MenuCode.Equals(input.MenuCode), ignoreQueryFilters: true).FirstOrDefaultAsync(cancellationToken);
            if (entity != null && !entity.IsDeleted)
            {
                throw Oh("编码已存在");
            }

            BaseMenuButtonResultDto baseMenuButtonResultDto = await CreateOrUpdate(input, entity, cancellationToken);
            return baseMenuButtonResultDto;
        }

        public async Task<List<BaseMenuButtonResultDto>> Copy(List<BaseMenuButtonDto> inputs, CancellationToken cancellationToken = default)
        {
            List<BaseMenuButtonResultDto> baseMenuButtonResultDtos = new List<BaseMenuButtonResultDto>();
            for (int i = 0; i < inputs.Count; ++i)
            {
                BaseMenuButtonDto input = inputs[i];
                BaseMenuButton entity = await MasterRepository.AsQueryable(bmb => bmb.Code.Equals(input.Code) && bmb.MenuCode.Equals(input.MenuCode), ignoreQueryFilters: true).FirstOrDefaultAsync(cancellationToken);
                if (entity != null && !entity.IsDeleted)
                {
                    continue;
                }
                input.Sort = i + 1;
                input.IsSplit = false;
                input.IsActive = true;
                input.Description = string.Empty;
                BaseMenuButtonResultDto baseMenuButtonResultDto = await CreateOrUpdate(input, entity, cancellationToken);
                baseMenuButtonResultDtos.Add(baseMenuButtonResultDto);
            }
            return baseMenuButtonResultDtos;
        }

        private async Task<BaseMenuButtonResultDto> CreateOrUpdate(BaseMenuButtonDto input, BaseMenuButton entity, CancellationToken cancellationToken)
        {
            BaseMenuButtonResultDto baseMenuButtonResultDto;
            if (entity == null)
            {
                baseMenuButtonResultDto = await base.Post(input, cancellationToken);
            }
            else
            {
                input.Id = entity.Id;
                entity.IsDeleted = false;
                baseMenuButtonResultDto = await UpdateAsync(input, entity, cancellationToken);
            }

            return baseMenuButtonResultDto;
        }
        #endregion

        #region 更新
        protected override async Task OnUpdateExecuting(BaseMenuButton entity, CancellationToken cancellationToken)
        {
            await base.OnUpdateExecuting(entity, cancellationToken);
            BaseMenuButton baseMenuButton = await MasterRepository.FirstOrDefaultAsync(bmb => !bmb.Id.Equals(entity.Id) && bmb.Code.Equals(entity.Code) && bmb.MenuCode.Equals(entity.MenuCode), cancellationToken: cancellationToken);
            if (baseMenuButton != null)
            {
                throw Oh("编码不存在或已被删除");
            }
        }
        #endregion
    }
}

